package Question20_4; public class Question { public static int count2sI(int num) { int countof2s = 0, digit = 0; int j = num, seendigits=0, position=0, pow10_pos = 1; /* maintaining this value instead of calling pow() is an 6x perf * gain (48s -> 8s) pow10_posMinus1. maintaining this value * instead of calling Numof2s is an 2x perf gain (8s -> 4s). * overall > 10x speedup */ while (j > 0) { digit = j % 10; int pow10_posMinus1 = pow10_pos / 10; countof2s += digit * position * pow10_posMinus1; /* we do this if digit <, >, or = 2 * Digit < 2 implies there are no 2s contributed by this * digit. * Digit == 2 implies there are 2 * numof2s contributed by * the previous position + num of 2s contributed by the * presence of this 2 */ if (digit == 2) { countof2s += seendigits + 1; } /* Digit > 2 implies there are digit * num of 2s by the prev. * position + 10^position */ else if(digit > 2) { countof2s += pow10_pos; } seendigits = seendigits + pow10_pos * digit; pow10_pos *= 10; position++; j = j / 10; } return(countof2s); } public static int count2sR(int n) { // Example: n = 513 // Base case if (n == 0) { return 0; } // Split apart 513 into 5 * 100 + 13. // [Power = 100; First = 5; Remainder = 13] int power = 1; while (10 * power < n) { power *= 10; } int first = n / power; int remainder = n % power; // Counts 2s from first digit int nTwosFirst = 0; if (first > 2) { nTwosFirst += power; } else if (first == 2) { nTwosFirst += remainder + 1; } // Count 2s from all other digits int nTwosOther = first * count2sR(power - 1) + count2sR(remainder); return nTwosFirst + nTwosOther; } public static void main(String[] args) { for (int i = 0; i < 1000; i++) { int v1 = count2sR(i); int v2 = count2sI(i); System.out.println("Between 0 and " + i + ": " + v1 + " " + v2); } } }